package models.players;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import models.Card;
import models.Player;
import models.StateManager.GameState;
import models.messages.AreYouHuman;
import models.messages.CloseConnection;
import models.messages.ConsoleMsg;
import models.messages.EvaluationsNames;
import models.messages.ExchangedCards;
import models.messages.ExchangingCards;
import models.messages.ItsYourTurn;
import models.messages.Licitating;
import models.messages.NewOpponent;
import models.messages.NewResults;
import models.messages.OpponentCards;
import models.messages.OpponentTurn;
import models.messages.OtherOpponents;
import models.messages.RemoveOpponent;
import models.messages.RevealCards;
import models.messages.TellYourCards;
import models.messages.TellYourName;
import models.messages.YourCards;
import play.Logger;
import play.libs.Akka;
import scala.concurrent.duration.Duration;
import akka.actor.ActorRef;

public class RandomBot extends Player
{
    public final ActorRef room;
    public List<Card>     hand;
    public Random         rand;

    public RandomBot(String uuid, String name, ActorRef room)
    {
        this.uuid = uuid;
        this.name = name;
        this.room = room;
        this.rand = new Random();
    }

    @Override
    public void onReceive(Object msg) throws Exception
    {
        try
        {

            if (msg instanceof ItsYourTurn)
            {
                ItsYourTurn yourTurn = (ItsYourTurn)msg;
                Akka.system()
                .scheduler()
                .scheduleOnce(Duration.create(4, TimeUnit.SECONDS),
                        new Runnable()
                {
                    private ItsYourTurn yourTurn;
                    private RandomBot pl;

                    public Runnable init(RandomBot pl, ItsYourTurn yourTurn)
                    {
                        this.pl = pl;
                        this.yourTurn = yourTurn;
                        return this;
                    }

                    @Override
                    public void run()
                    {
                        try
                        {
                            if(this.yourTurn.state.equals(GameState.EXCHANGING))
                            {
                                int num = 5 - this.pl.rand
                                        .nextInt(5);
                                List<Card> temp = new ArrayList<Card>(
                                        this.pl.hand);
                                for (int i = 0; i < num; ++i)
                                {
                                    temp.remove(this.pl.rand
                                            .nextInt(temp.size()));
                                }
                                this.pl.room
                                .tell(new ExchangingCards(
                                        this.pl.uuid, temp),
                                        null);
                            }
                            else if(this.yourTurn.state.equals(GameState.LICITATION1) || this.yourTurn.state.equals(GameState.LICITATION2))
                            {
                                int numb1 = this.pl.rand.nextInt(2);
                                int numb2 = this.pl.rand.nextInt((this.yourTurn.yourMoney - 10) > 0 ? this.yourTurn.yourMoney - 10 : 1) + 1;
                                int numb3 = this.yourTurn.maxBet - this.yourTurn.yourBet + numb2 + 1;

                                if(this.yourTurn.canCheck)
                                {
                                    if(numb1 == 0)
                                    {
                                        this.pl.room.tell(new Licitating(this.pl.uuid, "check", 0), null);
                                    }
                                    else
                                    {
                                        this.pl.room.tell(new Licitating(this.pl.uuid, "bet", numb2), null);
                                    }
                                }
                                else if(this.yourTurn.canRaise && numb1 == 0)
                                {
                                    this.pl.room.tell(new Licitating(this.pl.uuid, "raise", numb3), null);
                                }
                                else if(this.yourTurn.canCall)
                                {
                                    this.pl.room.tell(new Licitating(this.pl.uuid, "call", 0), null);
                                }
                                else if(this.yourTurn.canAllIn)
                                {
                                    this.pl.room.tell(new Licitating(this.pl.uuid, "allin", 0), null);
                                }
                                else
                                {
                                    this.pl.room.tell(new Licitating(this.pl.uuid, "fold", 0), null);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }.init(this, yourTurn), Akka.system().dispatcher());

            }
            else if (msg instanceof AreYouHuman)
            {
                this.getSender().tell(false, this.getSelf());
            }
            else if (msg instanceof TellYourName)
            {
                this.getSender().tell(this.name, this.getSelf());
            }
            else if (msg instanceof ConsoleMsg)
            {
                // nothing here...
            }
            else if (msg instanceof CloseConnection)
            {
            }
            else if (msg instanceof NewOpponent)
            {
            }
            else if (msg instanceof RemoveOpponent)
            {
            }
            else if (msg instanceof OtherOpponents)
            {
            }
            else if (msg instanceof YourCards)
            {
                YourCards yourCards = (YourCards) msg;
                this.hand = yourCards.cards;
                Collections.sort(this.hand, new Card.CardComparator());
            }
            else if (msg instanceof OpponentCards)
            {
            }
            else if (msg instanceof ExchangedCards)
            {
            }
            else if (msg instanceof OpponentTurn)
            {
            }
            else if (msg instanceof TellYourCards)
            {
                this.getSender().tell(this.hand, this.getSelf());
            }
            else if (msg instanceof RevealCards)
            {
            }
            else if (msg instanceof NewResults)
            {

            }
            else if (msg instanceof EvaluationsNames)
            {
            }
            else
            {
                Logger.error("[  RandomBot  ] Unhandled message: "
                        + msg.getClass().getName() + ".");
                this.unhandled(msg);
            }
        }
        catch (Exception e)
        {
            this.getSender().tell(new akka.actor.Status.Failure(e),
                    this.getSelf());
            throw e;
        }
    }

    @Override
    public void preStart()
    {
        Logger.debug("[  RandomBot  ] Spawned random bot.");
    }

    @Override
    public void postStop()
    {
        Logger.debug("[  RandomBot  ] Killed random bot.");
    }

}
